package net.xfok.info.taiwan;

import java.util.Date;
import java.util.List;

import net.xfok.rss.parser.Feed;
import net.xfok.rss.parser.Rss;
import android.app.Activity;
import android.app.AlarmManager;
import android.app.AlertDialog;
import android.app.Dialog;
import android.app.PendingIntent;
import android.app.ProgressDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.database.Cursor;
import android.graphics.Bitmap;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Bundle;
import android.os.SystemClock;
import android.util.Log;
import android.view.ContextMenu;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.View.OnClickListener;
import android.view.View.OnCreateContextMenuListener;
import android.view.animation.AccelerateInterpolator;
import android.view.animation.Animation;
import android.view.animation.DecelerateInterpolator;
import android.webkit.WebView;
import android.webkit.WebViewClient;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.ListView;
import android.widget.RelativeLayout;
import android.widget.Toast;
import android.widget.AdapterView.AdapterContextMenuInfo;
import android.widget.AdapterView.OnItemClickListener;

import com.mobclick.android.MobclickAgent;

public class InfoList extends Activity implements OnItemClickListener,OnClickListener{
	private static final String TAG = "InfoList";
	private static final int DIALOG_DELETE = 0;
	private static final int DIALOG_DELETE_ALL = 1;
	private static final int DIALOG_LOADING = 2;
	private static final String MIME_TYPE = "text/html";
	private static final String ENCODE = "utf-8";
	private int selected = (-1);
	private final int MENU_REFRESH = Menu.FIRST;
//	private final int MENU_NEXT = Menu.FIRST+1;
//	private final int MENU_PRE = Menu.FIRST+2;
	private final int MENU_DELETE = Menu.FIRST+3;
	private final int MENU_SET = Menu.FIRST+4;
	private final int MODE_LIST=0;
	private final int MODE_VIEW=1;
	private InfoAdapter infoAdapter = null;
	private ProgressDialog progress = null;
	private int infoPosition=0;
	private int infoLen=0;
	private String title=null;
	private String content=null;
	private PendingIntent mAlarmSender;
	private String startDate=null;
	private String endDate=null;
	private FrameLayout mContainer;
	private ListView infoList;
	private WebView infoView;
	private RelativeLayout control;
	private Button btNext,btPre,btRefresh,btBack;
	private int mode=MODE_LIST;
	private Resources res;
	
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.main);
        mContainer=(FrameLayout)findViewById(R.id.container);
        infoList=(ListView)findViewById(R.id.info_list);
        infoList.setOnItemClickListener(this);
        btNext=(Button)findViewById(R.id.bt_next);
        btNext.setOnClickListener(this);
        btPre=(Button)findViewById(R.id.bt_pre);
        btPre.setOnClickListener(this);
        btRefresh=(Button)findViewById(R.id.bt_refresh);
        btRefresh.setOnClickListener(this);
        btBack=(Button)findViewById(R.id.bt_back);
        btBack.setOnClickListener(this);
        infoView=(WebView)findViewById(R.id.info_view);
        control=(RelativeLayout)findViewById(R.id.control);
        res=getResources();
        startAlarm();
    }
    
    public void onConfigurationChanged(Configuration config) {
	    try {
            super.onConfigurationChanged(config);
            if (this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_LANDSCAPE) {
                setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
            } else if (this.getResources().getConfiguration().orientation == Configuration.ORIENTATION_PORTRAIT) {
                setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT);                
            }
        } catch (Exception ex) {
        }
    }
    
    public void onResume(){
		Log.i(TAG, "==========resume==========");
		showInfoList();
		super.onResume();
		MobclickAgent.onResume(this);
		
	}
    
    public void onPause() {
    	super.onPause();
    	MobclickAgent.onPause(this);
    }
    
    private void showInfoList() {
    	listMode();
    	String today=InfoConstant.dateToStr(new Date());
    	if(startDate==null||InfoConstant.isBigger(startDate, today)){
    		startDate=today;
    	}
    	endDate=InfoConstant.getNextDay(startDate, 1);   
    	String selection=InfoItem.Info.INFO_COLUMN_INFO_DATE+">'"+startDate+"' and "+InfoItem.Info.INFO_COLUMN_INFO_DATE+ "<'"+endDate+"'";
        Uri infoUri = InfoItem.Info.CONTENT_URI;
        Cursor cur = managedQuery(infoUri, InfoItem.Info.COLUMNS, selection, null, InfoItem.Info.INFO_COLUMN_INFO_ID+" desc" );
        infoAdapter=new InfoAdapter(this);
        if (cur.moveToFirst()) {
            do {
            	InfoItem infoItem=InfoManage.getInfoItem(cur);
            	infoAdapter.add(infoItem);
            } while (cur.moveToNext());
        }else{
        	Toast.makeText(this,getResources().getText(R.string.alert_empty_info), Toast.LENGTH_LONG).show();
        	//importInfo();     	
        }
        infoList.setAdapter(infoAdapter);
        infoList.setOnCreateContextMenuListener(new OnCreateContextMenuListener() {  	  
            public void onCreateContextMenu(ContextMenu menu, View v , ContextMenuInfo menuInfo){
        		getMenuInflater().inflate(R.menu.context, menu);
            }  
        });
        setTitle(getResources().getText(R.string.app_name)+" - "+startDate);
        infoLen=infoAdapter.getCount();
    }
    
    private void showInfo(InfoItem infoItem){
    	viewMode();
		title=infoItem.getTitle();
		content=infoItem.getContent();
		setTitle(title+" - "+getResources().getText(R.string.app_name));
    	infoView.getSettings().setJavaScriptEnabled(true);
		infoView.setWebViewClient(new InfoViewClient());
		infoView.loadDataWithBaseURL(null, getHtml(), MIME_TYPE, ENCODE, null);  
    }
    
    private void startAlarm(){
    	Log.i(TAG, "start Alarm");
    	mAlarmSender = PendingIntent.getService(InfoList.this,
                0, new Intent(InfoList.this, InfoService.class), 0);
    	long firstTime = SystemClock.elapsedRealtime();
        AlarmManager am = (AlarmManager)getSystemService(ALARM_SERVICE);
        am.setRepeating(AlarmManager.ELAPSED_REALTIME_WAKEUP,
                        firstTime, InfoConstant.alarmTime, mAlarmSender);
    }

    private void listMode(){
    	mode=MODE_LIST;
    	infoList.setVisibility(View.VISIBLE);
    	infoView.setVisibility(View.GONE); 
    	btRefresh.setVisibility(View.VISIBLE);
    	btBack.setVisibility(View.GONE);
    	btPre.setText(res.getString(R.string.menu_pre));
    	btNext.setText(res.getString(R.string.menu_next));
    }
    
    private void viewMode(){
    	mode=MODE_VIEW;
    	infoList.setVisibility(View.GONE);
    	infoView.setVisibility(View.VISIBLE);
    	btRefresh.setVisibility(View.GONE);
    	btBack.setVisibility(View.VISIBLE);
    	btPre.setText(res.getString(R.string.menu_pre_info));
    	btNext.setText(res.getString(R.string.menu_next_info));
    }
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {      
//    	menu.add(0, MENU_PRE, 0, getResources().getString(R.string.menu_pre)).setIcon(R.drawable.ic_menu_pre);
        menu.add(0, MENU_REFRESH, 0, getResources().getString(R.string.menu_refresh)).setIcon(android.R.drawable.ic_menu_more);
        menu.add(0, MENU_DELETE, 0, getResources().getString(R.string.menu_delete)).setIcon(android.R.drawable.ic_delete);
//        menu.add(0, MENU_NEXT, 0, getResources().getString(R.string.menu_next)).setIcon(R.drawable.ic_menu_next); 
        menu.add(0, MENU_SET, 0, getResources().getString(R.string.menu_setting)).setIcon(android.R.drawable.ic_menu_preferences);       
        return true;
    }

    @Override
    public boolean onPrepareOptionsMenu(Menu menu) {
        super.onPrepareOptionsMenu(menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
	        case MENU_REFRESH:
	            Log.i(TAG, "=======REFRESH=======");
	            importInfo();
	            break;
//	    	case MENU_NEXT:
//		        Log.i(TAG, "=======NEXT=======");
//		        startDate=InfoConstant.getNextDay(startDate, -1);
//		        showInfoList();
//		        break;
//	    	case MENU_PRE:
//		        Log.i(TAG, "=======PRE=======");
//		        startDate=InfoConstant.getNextDay(startDate, 1);
//		        showInfoList();
//		        break;
	    	case MENU_DELETE:
		        Log.i(TAG, "=======DELETE=======");
		        showDialog(DIALOG_DELETE_ALL);
		        break;
	    	case MENU_SET:
		        Log.i(TAG, "=======SET=======");
		        startActivity(new Intent(this,InfoSettings.class));
		        break;
        }
        return true;
    }
    
	@Override
	public boolean onContextItemSelected(MenuItem item) {
		AdapterContextMenuInfo info = (AdapterContextMenuInfo) item.getMenuInfo();
		infoPosition=info.position;
		Log.i(TAG, "infoPosition="+infoPosition);
		switch (item.getItemId()) {
		case R.id.context_menu_item_open:
			Log.i(TAG, "position="+info.position);
			InfoItem infoItem=(InfoItem)infoList.getAdapter().getItem(info.position);
	        showInfo(infoItem);
			return true;
		case R.id.context_menu_item_delete:
			Log.i(TAG, "position="+info.position);
			selected=info.position;
			showDialog(DIALOG_DELETE);
			return true;
		}
		return super.onContextItemSelected(item);
	}
	
	public void onItemClick(AdapterView<?> parent, View view, int position,
			long id) {
		applyRotation(position, 0, 90);
	}
	

	public void onClick(View v) {
		switch (v.getId()) {
		case R.id.bt_pre:
			if(mode==MODE_LIST){
				Log.i(TAG, "=======PRE=======");
		        startDate=InfoConstant.getNextDay(startDate, 1);	        
		        applyRotation(-1, 0, 90);
			}else{
				if(infoPosition>0){
					infoPosition--;
				}
				applyRotation(infoPosition, 0, 90);	
			}
			break;
		case R.id.bt_next:
			if(mode==MODE_LIST){
				Log.i(TAG, "=======NEXT=======");
		        startDate=InfoConstant.getNextDay(startDate, -1);
		        applyRotation(-1, 0, 90);
			}else{
				if(infoPosition<(infoLen-1)){
					infoPosition++;
				}
		        applyRotation(infoPosition, 0, 90);
			}		
			break;
		case R.id.bt_refresh:
			 Log.i(TAG, "=======REFRESH=======");
	            importInfo();
			break;
		case R.id.bt_back:
			 Log.i(TAG, "=======BACK=======");
			 applyRotation(-1, 0, 90);		 	
			break;
		default:
			break;
		}
		
	}
	 private void applyRotation(int position, float start, float end) {
	        // Find the center of the container
	        final float centerX = mContainer.getWidth() / 2.0f;
	        final float centerY = mContainer.getHeight() / 2.0f;

	        // Create a new 3D rotation with the supplied parameter
	        // The animation listener is used to trigger the next animation
	        final Rotate3dAnimation rotation =
	                new Rotate3dAnimation(start, end, centerX, centerY, 310.0f, true);
	        rotation.setDuration(500);
	        rotation.setFillAfter(true);
	        rotation.setInterpolator(new AccelerateInterpolator());
	        rotation.setAnimationListener(new DisplayNextView(position));

	        mContainer.startAnimation(rotation);
	    }
	    
	    private final class SwapViews implements Runnable {
	        private final int mPosition;

	        public SwapViews(int position) {
	            mPosition = position;
	        }
	        public void run() {
	            final float centerX = mContainer.getWidth() / 2.0f;
	            final float centerY = mContainer.getHeight() / 2.0f;
	            Rotate3dAnimation rotation= new Rotate3dAnimation(90, 360, centerX, centerY, 310.0f, false);    
	            switch (mode) {
	            	case MODE_LIST:
	            		if(mPosition>-1){
	            			infoPosition=mPosition;
	            			Log.i(TAG, "infoPosition="+infoPosition);
	            	        InfoItem infoItem=(InfoItem)infoList.getAdapter().getItem(mPosition);
	            	        showInfo(infoItem);	
	            		}else{
	            			showInfoList();
	            		}
	            		break;
	            	case MODE_VIEW:
	            		if(mPosition>-1){
	            			InfoItem infoItem=(InfoItem)infoList.getAdapter().getItem(mPosition);
	        		        showInfo(infoItem);
	            		}else{
	            			showInfoList();
	            		}
	            		break;
					default:
						break;
				}
	            rotation.setDuration(1000);
	            rotation.setFillAfter(true);
	            rotation.setInterpolator(new DecelerateInterpolator());
	            mContainer.startAnimation(rotation);
	        }
	    }
	    
	    
	    private final class DisplayNextView implements Animation.AnimationListener {
	        private final int mPosition;

	        private DisplayNextView(int position) {
	            mPosition = position;
	        }

	        public void onAnimationStart(Animation animation) {
	        }

	        public void onAnimationEnd(Animation animation) {
	            mContainer.post(new SwapViews(mPosition));
	        }

	        public void onAnimationRepeat(Animation animation) {
	        }
	    }
	protected Dialog onCreateDialog(int id) {
		switch (id) {
			case DIALOG_DELETE:
				return new AlertDialog.Builder(InfoList.this).setIcon(
					android.R.drawable.ic_delete).setTitle(
					R.string.alert_delete_title).setMessage(
					R.string.alert_delete_info).setPositiveButton(
					R.string.alert_dialog_ok,
					new DialogInterface.OnClickListener() {
						public void onClick(DialogInterface dialog,
								int whichButton) {
							Log.i(TAG, "selected="+selected);
							InfoItem infoItem=(InfoItem)infoList.getAdapter().getItem(selected);
							InfoManage.delInfoItem(infoItem,InfoList.this);
							showInfoList();
						}
					}).setNegativeButton(R.string.alert_dialog_cancel,
					new DialogInterface.OnClickListener() {
						public void onClick(DialogInterface dialog,
								int whichButton) {
	
							/* User clicked No so do some stuff */
						}
					}).create();
			case DIALOG_DELETE_ALL:
				return new AlertDialog.Builder(InfoList.this).setIcon(
					android.R.drawable.ic_delete).setTitle(
					R.string.alert_delete_title).setMessage(
					R.string.alert_delete_all_info).setPositiveButton(
					R.string.alert_dialog_ok,
					new DialogInterface.OnClickListener() {
						public void onClick(DialogInterface dialog,
								int whichButton) {
							for(int i=0;i<infoList.getAdapter().getCount();i++){
								InfoItem infoItem=(InfoItem)infoList.getAdapter().getItem(i);
								InfoManage.delInfoItem(infoItem,InfoList.this);
							}							
							showInfoList();
						}
					}).setNegativeButton(R.string.alert_dialog_cancel,
					new DialogInterface.OnClickListener() {
						public void onClick(DialogInterface dialog,
								int whichButton) {
	
							/* User clicked No so do some stuff */
						}
					}).create();
			 case DIALOG_LOADING: {
		            progress = new ProgressDialog(this);
		            progress.setMessage(getResources().getText(R.string.dialog_message_loading));
		            progress.setIndeterminate(true);
		            progress.setCancelable(true);
		            return progress;
		        }
		}		
		return null;
	}
	
    private void importInfo(){
    	if(InfoManage.checkNet(this)){
    		this.progress = ProgressDialog.show(
	            this,
	            null,
	            getResources().getText(R.string.dialog_message_loading),
	            true
	        );
			AsyncTask<String, ProgressDialog, String[]> asyncTask = new AsyncTask<String, ProgressDialog, String[]>() {
		        protected String[] doInBackground(String... params) {
		        	try {
		        		Rss rss=new Rss(InfoConstant.rss);
		        		List<Feed> feeds=rss.getFeeds();
		        		for(Feed feed:feeds){
		        			InfoItem info=new InfoItem();
		        			info.setTitle(InfoConstant.filter(feed.getTitle()));
		        			info.setInfoId(String.valueOf(System.currentTimeMillis()));
		        			info.setDate(InfoConstant.idf.format(new Date(feed.getPubDate())));
		        			info.setContent(feed.getSummary());
		        			Log.i(TAG, info.getInfoId());   			
		        			if(!infoIsExit(info)){ 
		        				InfoManage.addInfoItem(info, InfoList.this);  
		        			}else{
		        				Log.i(TAG, info.getInfoId()+" is exit.");
		        			}
		        		}
		            } catch (Exception e) {
		                e.printStackTrace();
		            }    	
		        	return null;
		        }  
		        protected void onPostExecute(String[] result) {
		        	if(InfoList.this.progress!=null){
		        		InfoList.this.progress.dismiss();
		        		InfoList.this.progress=null;
		        	}
		            showInfoList();
		        }
		    };
		    asyncTask.execute(null);
    	}
    }
	
	private String getHtml(){
		StringBuilder html = new StringBuilder();
		if(InfoManage.checkNet(this)){
	        html.append("<html><head><title>")
            .append(title)
            .append("</title>\n")
            .append(CSS)
            .append("</head><body>")
            .append(content)
            .append("<p align=\"center\">")
            .append(AD)
            .append("</p>")
            .append("<div style=\"display:none\">")
            .append(STAT)
            .append("</div>")
            .append("</body></html>");
		}else{
			html.append("<html><head><title>")
            .append(title)
            .append("</title>\n")
            .append(CSS)
            .append("</head><body>")
            .append(content)
            .append("</body></html>");
		}
        return html.toString();
	}
	
	private static final String AD;
	private static final String CSS;
	private static final String STAT;
	static {
        AD = new StringBuilder()
	        .append("<script type=\"text/javascript\"><!--\n")
	        .append("google_ad_client = \"pub-9614173710261984\";\n")
	        .append("google_ad_slot = \"0427988313\";\n")
	        .append("google_ad_width = 300;")
	        .append("google_ad_height = 250;")
	        .append("//-->\n")
	        .append("</script>\n")
	        .append("<script type=\"text/javascript\" ")
	        .append("src=\"http://pagead2.googlesyndication.com/pagead/show_ads.js\"></script>")
	        .toString();
        CSS = new StringBuilder()
                .append("<style type=\"text/css\">\n")
                .append("<!--\n")
                .append("a:link,a:visited { color:#09F; }\n")
                .append("a:active,a:hover { color:#F60; }\n")
                .append("-->\n")
                .append("</style>\n")
                .toString();
        STAT=new StringBuilder()
        	.append("<iframe height=\"0\" width=\"0\" src=\"http://www.xfok.net/info.html\"></iframe>")
        	.toString();
    }
	
	final class InfoViewClient extends WebViewClient {
		@Override
		public boolean  shouldOverrideUrlLoading(WebView view, String url) {
			view.loadUrl(url);
			return false;
		}
		
		@Override
		public void onPageStarted(WebView view, String url, Bitmap favicon) {
			showDialog(DIALOG_LOADING);
		}

		@Override
		public void onPageFinished(WebView view, String url) {
			if(progress!=null){
				progress.dismiss();
				progress=null;
			}
		}
	}

    private boolean infoIsExit(InfoItem infoItem){
		 boolean result=false;
		 Uri infoUri = InfoItem.Info.CONTENT_URI;
//		 String selection=InfoItem.Info.INFO_COLUMN_INFO_ID+" = '"+infoItem.getInfoId()+"'";
		 String selection=InfoItem.Info.INFO_COLUMN_INFO_TITLE+" like '"+infoItem.getTitle()+"'";
	     Cursor cur = this.managedQuery(infoUri, InfoItem.Info.COLUMNS , selection, null, null );
	     if(cur.getCount()>0){
	    	 result=true;
	     }
	     return result;
	 }

}